package com.twq.collection.framework

import scala.collection.mutable.ArrayBuffer

/**
 * Created by tangweiqun on 2017/12/10.
 */
object TraversableTest {
  def main(args: Array[String]): Unit = {
    //1、Traversable 中只定义了一个抽象方法： def foreach[U](f: Elem => U)
    // 这个方法的功能就是遍历集合中的每一个元素，然后将函数f应用在每一个元素上
    // Elem表示集合元素的类型，U表示函数f的返回类型，函数f的结果值将会丢弃

    //2、Traversable所有的方法分类以及含义
    val xs = Traversable(1, 2, 4, 1)
    //抽象方法(Abstract Method)
    xs foreach println

    //添加方法(Addition)
    // 将两个Traversable拼接在一起，或者将Iterator中的所有元素拼接到Traversable中
    val ys = Traversable(2, 3)
    xs ++ ys

    //映射方法(Maps)
    // 将一个方法应用到集合中的每一个元素，然后返回新的集合
    xs map (i => (i + 1).toString())
    xs flatMap (_.to(5))
    xs collect { case i if (i == 2) => i * 3 }

    //转换方法(Conversions)
    //将Traversable转换成更具体的集合
    val x = Traversable(2, 3)
    x.toArray
    x.toList
    x.toIterable
    x.toSeq
    x.toIndexedSeq
    x.toStream
    x.toSet
    //x.toMap // x必须是key value类型的集合

    //拷贝方法(Copying)
    //将集合元素拷贝到Buffer或者Array中
    val buff = new ArrayBuffer[Int]()
    xs.copyToBuffer(buff)
    val arr = new Array[Int](4)
    xs.copyToArray(arr, 1, 2) //从拷贝xs前面两个元素到arr中(从arr的下标为2开始)

    //大小信息方法(Size info)
    xs.isEmpty
    xs.nonEmpty
    xs.size
    xs.hasDefiniteSize //如果Traversable知道有有限的长度则返回true

    //检索元素方法(Element Retrieval)
    //对于head和last不是所有的集合返回都是固定值，比如Set，因为Set是无序的
    xs.head
    xs.headOption
    xs.last
    xs.lastOption
    xs find (_ == 3)

    //子集合方法(Subcollections)
    xs.tail //除了xs.head的所有的元素集合
    xs.tails //Seq(1, 2, 4, 1).tails = Iterator( List(1, 2, 4, 1),List(2, 4, 1),List(4, 1),List(1),Nil)
    xs.init //除了xs.last的所有元素的集合
    xs.slice(1, 3) //List(2, 4)
    xs.take(2)
    xs.drop(2) //除了take(2)外的其他元素的集合
    xs.takeWhile(_ == 1) //从集合的头开始提取符合条件的数据，一旦碰到不符合的数据元素则退出
    xs.dropWhile(_ == 1) //从集合的头开始删除符合条件的数据，一旦碰到不符合的数据元素则退出
    xs.filter(_ == 2) //过滤出符合条件的元素的集合
    xs.withFilter(_ == 2) //不是严格意义上上的filter，不像filter那样会产生新的集合
    xs.filterNot(_ == 2) //过滤出不符合条件的元素的集合

    //切分方法(Subdivisions)
    //在指定的位置对集合介个, 返回 pair of collections (xs take n, xs drop n)
    xs.splitAt(3) //res20: (Seq[Int], Seq[Int]) = (List(1, 2, 4),List(1))
    //根据指定的条件对集合进行切割, 返回 pair of collections (xs takeWhile p, xs.dropWhile p)
    xs.span(_ == 1) //res22: (Seq[Int], Seq[Int]) = (List(1),List(2, 4, 1))
    //返回集合对，第一个集合包括了符合条件的元素的集合，第二个集合包括了不符合条件的元素的集合
    //(xs filter p, xs.filterNot p)
    xs.partition(_ == 1) //res24: (Seq[Int], Seq[Int]) = (List(1, 1),List(2, 4))
    //按照f来group集合成Map
    xs.groupBy(_ + 1) //res25: scala.collection.immutable.Map[Int,Seq[Int]] = Map(2 -> List(1, 1), 5 -> List(4), 3 -> List(2))

    //元素判断方法(Element Conditions)
    xs.forall(_ > 0) //判断集合xs中的所有元素是否大于0
    xs.exists(_ > 2) //判断集合xs中是否有大于2的元素
    xs.count(_ > 2) //计算集合xs中大于2的数量

    //折叠方法(Folds)
    //对集合中的连续的元素应用二元操作
    (0 /: xs) (_ + _)
    xs.foldLeft(0)(_ + _)
    (xs :\ 0) (_ + _)
    xs.foldRight(0)(_ + _)
    xs.reduceLeft(_ + _)
    xs.reduceRight(_ + _)

    //Specific Folds
    xs.sum
    xs.product
    xs.min
    xs.max

    //Strings
    val sb = new StringBuilder
    xs.addString(sb, "[", ",", "]")
    xs.mkString("[", ",", "]")
    xs.stringPrefix

    //Views
    //lazy计算特性的集合
    xs.view(1, 3)
  }
}
